<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>free-api-use-by-vue3</title>
    <style>
      body {
        background: linear-gradient(rgba(111, 111, 111, 0.5), rgba(111, 111, 111, 0.5)),
          url('https://api.vvhan.com/api/bing');

        color: #fff;
      }

      audio,
      audio:focus,
      input,
      textarea,
      button,
      select {
        height: 30px;
        border-radius: 1.5%;
        outline: none;
        border: none;
      }

      .container {
        display: flex;
        flex-wrap: wrap;
        justify-content: space-evenly;
      }

      button,
      select {
        cursor: pointer;
      }

      img {
        border-radius: 1.5%;
      }

      div[id^='app'] {
        text-align: center;
      }

      h2 {
        background-image: linear-gradient(#2de2ff, #8b67fb);
        /* background-image: linear-gradient(120deg, #30cfd0 0%, #8b67fb 30%, #2de2ff 60%); */
        background-clip: text;
        -webkit-background-clip: text;
        color: transparent;
      }

      @media (max-width: 767px) {
        div[id^='app'] {
          width: 100%;
        }
        div[id^='app'] img {
          max-width: 100%;
        }
        div[id^='app'] textarea {
          width: 100% !important;
        }
      }
      @media (min-width: 768px) and (max-width: 992px) {
        div[id^='app'] {
          width: 50%;
        }
      }
      @media (min-width: 992px) {
        div[id^='app'] {
          width: 33.33%;
        }
      }
    </style>
    <div id="hans-bolang"></div>
    <script src="https://api.vvhan.com/api/bolang"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue@3"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script type="importmap">
      {
        "imports": {
          "vue": "https://cdn.jsdelivr.net/npm/vue@3/dist/vue.esm-browser.js"
        }
      }
    </script>
  </head>
  <body>
    <div class="container">
      <div id="app1" class="random-avatar-container">
        <h2>👇👇随机头像👇👇</h2>
        <select v-model="avatarParams.method">
          <option value="zsy">手机电脑自动判断</option>
          <option value="pc">电脑端</option>
          <option value="mobile">手机端</option>
        </select>
        &nbsp;
        <select v-model="avatarParams.lx">
          <option value="a1">男生头像</option>
          <option value="b1">女生头像</option>
          <option value="c1">动漫头像</option>
          <option value="c2">动漫女生头像</option>
          <option value="c3">动漫男生头像</option>
        </select>
        <br />
        <br />
        <img :src="imgurl" alt="avatar" @click="setAvatar" style="cursor: pointer" />
      </div>
      <div id="app2" class="qq-info-container">
        <h2>👇👇获取 QQ 昵称和头像👇👇</h2>
        <form>
          <input type="text" placeholder="请输入 QQ 号码" v-model.number.trim="qq" /> &nbsp;
          <button @click.prevent="searchQqInfo">搜索</button>
        </form>
        <br />
        <div>QQ 昵称：{{qqInfo.name}}</div>
        <br />
        <div>QQ 头像: <img :src="qqInfo.imgurl" alt="avatar" style="vertical-align: top" /></div>
      </div>
      <div id="app3" class="random-song">
        <h2>👇👇随机歌曲👇👇</h2>
        <select v-model="songParams.sort">
          <option value="热歌榜">热歌榜</option>
          <option value="新歌榜">新歌榜</option>
          <option value="飙升榜">飙升榜</option>
          <option value="原创">原创</option>
        </select>
        &ensp;
        <button @click="getSong">切歌</button> <br />
        <br />
        <div class="info">
          <div>歌名：{{songInfo.name}}</div>
          <br />
          <div>歌手：{{songInfo.auther}}</div>
          <br />
          <div style="display: flex; justify-content: center; align-items: center">
            歌曲：
            <img
              :src="songInfo.picUrl"
              alt="pic"
              style="width: 30px; height: 30px; border-radius: 50%; margin-right: 10px"
            />
            <audio autoplay controls volume="0.3" :src="songInfo.mp3url" @ended="getSong">
              您的浏览器不支持 audio 元素。
            </audio>
          </div>
        </div>
      </div>
      <div id="app4" class="text-to-speech">
        <h2>👇👇文字转语音👇👇</h2>
        <textarea style="width: 90%; height: 200px" placeholder="请输入待转换的内容" v-model="text"></textarea> <br />
        <br />
        <audio controls volume="0.5" :src="'https://api.vvhan.com/api/song.php?txt=' + text">
          您的浏览器不支持 audio 元素。
        </audio>
      </div>
      <div id="app5" class="weather-card">
        <h2>👇👇天气卡片👇👇</h2>
        <img :src="'https://api.vvhan.com/api/ip?tip=Hello, ' + timeState" alt="^_^ ^_^ ^_^" style="width: 80%" />
      </div>
      <div id="app6" class="str-encryption">
        <h2>👇👇字符串加解密👇👇</h2>
        <form>
          <input type="text" placeholder="请输入自定义密匙" v-model.trim="myKey" style="width: 90%" /> <br />
          <br />
          <button id="en-btn" @click.prevent="handleEncrypt('en')">加密</button> &ensp;
          <button id="de-btn" @click.prevent="handleEncrypt('de')" disabled>解密</button> <br />
        </form>
        <br />
        <textarea style="width: 90%; height: 200px" placeholder="待加密内容" v-model="content"></textarea>
      </div>
    </div>
    <script type="module">
      import { createApp, ref, toRefs, reactive, watch, computed } from 'vue'
      /* 👇👇随机头像👇👇 */
      const app1 = createApp({
        setup() {
          const imgurl = ref('')
          const avatarParams = reactive({
            method: 'zsy', // 壁纸端
            lx: 'c1', // 头像类型
            format: 'json', // 壁纸格式 - [json|images]
          })
          // 设置头像
          const setAvatar = () => {
            axios
              .get('https://api.btstu.cn/sjtx/api.php', {
                params: avatarParams,
              })
              .then(({ data }) => {
                imgurl.value = data.imgurl
              })
              .catch((err) => {
                console.log('err', err)
              })
          }
          // 监听参数变化
          watch(avatarParams, () => setAvatar(), { immediate: true })
          return { imgurl, avatarParams, setAvatar }
        },
      }).mount('#app1')

      /* 👇👇获取 QQ 昵称和头像👇👇 */
      const app2 = createApp({
        setup() {
          const qq = ref(10001)
          let qqInfo = reactive({ imgurl: '', name: '' })
          // 搜索 QQ 信息
          const searchQqInfo = async () => {
            if (!qq.value) return
            const res = await axios({
              url: 'https://api.btstu.cn/qqxt/api.php',
              method: 'get',
              params: { qq: qq.value },
            })
            qqInfo.imgurl = res.data.imgurl
            qqInfo.name = res.data.name
          }
          searchQqInfo()
          return { qq, qqInfo, searchQqInfo }
        },
      }).mount('#app2')

      /* 👇👇随机歌曲👇👇 */
      const app3 = createApp({
        setup() {
          const state = reactive({
            songInfo: {
              id: undefined,
              auther: '',
              name: '',
              mp3url: '',
              picUrl: '',
            },
          })
          const songParams = reactive({
            type: 'json',
            sort: '热歌榜',
          })

          // 获取歌曲
          const getSong = () => {
            axios
              .get('https://api.vvhan.com/api/rand.music', {
                params: songParams,
              })
              .then(({ data }) => {
                state.songInfo = data.info
              })
              .catch((err) => {
                console.log('err', err)
              })
          }
          watch(songParams, () => getSong(), { immediate: true })

          return { songParams, ...toRefs(state), getSong }
        },
      }).mount('#app3')

      /* 👇👇文字转语音👇👇 */
      const app4 = createApp({
        setup() {
          const text = ref('只因你太美')
          return { text }
        },
      }).mount('#app4')

      /* 👇👇天气卡片👇👇 */
      const app5 = createApp({
        setup() {
          const timeState = computed(() => {
            const currentDate = new Date()
            const hours = currentDate.getHours()
            let state = ``
            if (hours < 6) {
              state = `凌晨好!`
            } else if (hours < 9) {
              state = `早上好!`
            } else if (hours < 12) {
              state = `上午好!`
            } else if (hours < 14) {
              state = `中午好!`
            } else if (hours < 17) {
              state = `下午好!`
            } else if (hours < 19) {
              state = `傍晚好!`
            } else if (hours <= 24) {
              state = `晚上好!`
            }
            return state
          })

          return { timeState }
        },
      }).mount('#app5')

      /* 👇👇字符串加解密👇👇 */
      const app6 = createApp({
        setup() {
          const today = (function () {
            const year = new Date().getFullYear().toString()
            const month =
              new Date().getMonth() < 9 ? '0' + (new Date().getMonth() + 1) : (new Date().getMonth() + 1).toString()
            const date = new Date().getDate() < 10 ? '0' + new Date().getDate() : new Date().getDate().toString()
            return year + month + date
          })()
          // 密匙
          const myKey = ref(today)
          const content = ref('只因你太美')
          // 加/解密
          const handleEncrypt = async (type) => {
            // if (!/^\d{1,8}$/.test(myKey.value)) return alert('密匙必须为 1-8 位纯数字')
            const { data } = await axios.get('https://api.vvhan.com/api/jm', {
              params: {
                key: myKey.value,
                string: content.value,
                type,
              },
            })
            switch (type) {
              case 'en':
                content.value = data.enmissString
                document.getElementById('de-btn').disabled = false
                break
              case 'de':
                content.value = data.demissString
                document.getElementById('en-btn').disabled = false
                break
            }
            document.getElementById(type + '-btn').disabled = true
          }

          return { myKey, content, handleEncrypt }
        },
      }).mount('#app6')
    </script>
  </body>
</html>
